import { tableOpBtns } from './buttons';
import { objectMerge, oneOf } from '@/utils';

export default {
  name: 'data-table',
  componentName: 'data-table',
  props: {
    loadData: Function,
    columns: {
      type: Array,
      default: function() {
        return [];
      },
    },
    tooltipEffect: {
      type: String,
      default: 'light',
    },
    pageLayout: {
      type: String,
      default: 'total, sizes, prev, pager, next, jumper',
    },
    opBtns: {
      type: Array,
      default: function() {
        return [];
      },
    },
    customBtns: {
      type: Array,
      default: function() {
        return [];
      },
    },
    pagination: {
      type: Boolean,
      default: true,
    },
    pageSmall: {
      type: Boolean,
      default: true,
    },
    pagerCount: {
      type: Number,
      default: 7,
    },
    pageSize: {
      type: Number,
      default: 20,
    },
    pageSizes: {
      type: Array,
      default: function() {
        return [10, 20, 30, 40, 50, 100];
      },
    },
  },
  data() {
    return {
      data: [],
      permissions: [],
      btnOpArray: [],
      loading: false,
      currentPage: 1,
      total: 0,
      queryForm: {},
      selection: [],
      checkAll: false,
      sortName: null,
      sortOrder: null,
      _pageSize: 20,
    };
  },
  computed: {
    hasPagination() {
      return !!this.loadData;
    },
  },
  methods: {
    toggleRowSelection(row, selected) {
      this.$refs.table.toggleRowSelection(row, selected);
    },
    selectAll() {
      var value = this.data;
      if (this.selection.length === this.data.length) {
        this.checkAll = true;
      } else {
        this.checkAll = false;
      }
      if (this.checkAll === true) {
        this.$refs.table.clearSelection();
      } else {
        if (value) {
          for (var i = 0; i < value.length; i++) {
            this.$refs.table.toggleRowSelection(value[i], true);
          }
        }
      }
      this.$refs.table.selectAll();
      this.$emit('select-all', this.$refs.table.selection);
    },
    clearQueryCriteria() {
      this.queryForm = {};
      this.$refs.table.clearSort();
      this.sortName = '';
      this.$refs.table.clearSelection();
      this.currentPage = 0;
    },
    reload(params) {
      this.queryForm = {};
      if (params) {
        this._pageSize = this.pageSize;
        objectMerge(this.queryForm, params);
      } else {
        this.queryForm = {};
      }

      // console.error(this.$attrs)
      // bug ，修改默认排序
      if (!this.sortName && !this.sortOrder && this.$attrs['default-sort']) {
        this.sortName = this.$attrs['default-sort']['prop'];
        this.sortOrder = this.$attrs['default-sort']['order'];
      }
      this.handleCurrentChange(1);
    },
    refresh() {
      this.handleCurrentChange(1);
    },
    // 重新加载，页面不变
    reloadCurrent() {
      this.getDataFromServer();
    },
    doLayout() {
      this.$refs.table.doLayout();
    },
    handleCurrentChange(currentPage) {
      this.currentPage = currentPage;
      this.getDataFromServer();
    },
    handleSizeChange(size) {
      this._pageSize = size;
      setTimeout(() => {
        this.getDataFromServer();
      }, 500);
    },
    clearSelection() {
      this.$refs.table.clearSelection();
    },
    setCurrentRow(row) {
      this.$refs.table.setCurrentRow(row);
    },
    toggleSelection(value) {
      this.$refs.table.clearSelection();
      if (value) {
        /*
       for(var i=0;i<value.length;i++){
         this.$refs.table.toggleRowSelection(value[i],true)
        }
        */
        this.value.forEach(row => {
          this.$refs.table.toggleRowSelection(row);
        });
      }
    },
    handleTableOp(btn) {
      var rowKey = this.$attrs['row-key'] ? this.$attrs['row-key'] : 'id';
      var ids = this.selection.map((d) => d[rowKey]);
      this.$emit('table-op', btn.key, ids, this.selection, btn);
    },
    handleOpDisabled(btn) {
      return (btn.controller === undefined || btn.controller) && (!this.selection || this.selection.length === 0);
    },
    handleOpGroupDisabled(btns) {
      for (var i = 0; i < btns.length; i++) {
        if (!this.handleOpDisabled(btns[i])) {
          return false;
        }
      }
      return true;
    },
    calcBtn() {
      var exportBtn = [];
      this.btnOpArray = [];
      this.opBtns.forEach(key => {
        let permission = null;
        // 权限以__分隔
        if (key.indexOf('__' !== -1)) {
          permission = key.split('__')[1];
          key = key.split('__')[0];
        }
        // 权限控制
        if (!permission || this.permissions.includes(permission)) {
          if (key === 'export') {
            exportBtn = ['exportAll', 'exportList', 'exportPic', 'exportAttach'];
          } else {
            if (tableOpBtns[key]) {
              if (key.indexOf('export') === 0) {
                if (!oneOf(key, exportBtn)) {
                  exportBtn.push(key);
                }
              } else {
                this.btnOpArray.push({ ...tableOpBtns[key], loading: false, permission: permission });
              }
            }
          }
        }
      });

      if (this.customBtns) {
        this.customBtns.forEach(btn => {
          btn['loading'] = false;
        });
        this.btnOpArray = this.btnOpArray.concat(this.customBtns.filter(btn => !btn.permission || this.permissions.includes(btn.permission)));
      }
      // 计算导出按钮的位置
      if (exportBtn.length > 0) {
        var index = this.btnOpArray.length > 2 ? 1 : this.btnOpArray.length;
        if (exportBtn.length === 1) {
          this.btnOpArray.splice(index, 0, tableOpBtns[exportBtn[0]]);
        } else {
          var exportBtnObj = [];
          exportBtn.forEach(ele => {
            exportBtnObj.push(tableOpBtns[ele]);
          });
          this.btnOpArray.splice(index, 0, {
            key: 'export',
            children: exportBtnObj,
          });
        }
      }
      // 处理更多
      if (this.btnOpArray.length > 4) {
        var moreBtn = this.btnOpArray.slice(3, this.btnOpArray.length);
        this.btnOpArray = this.btnOpArray.slice(0, 3);
        this.btnOpArray.push(
          {
            key: 'more',
            children: moreBtn,
          }
        );
      }
    },
    renderMoreBtn(btns) {
      return btns.map(btn => {
        return (
          <el-dropdown-item v-loading={ btn.loading } command={btn} disabled={this.handleOpDisabled(btn)}>{btn.label}</el-dropdown-item>
        );
      });
    },
    handleCommand(btn) {
      this.handleTableOp(btn);
    },
    renderOpBtn() {
      return this.btnOpArray.map(btn => {
        if (btn.key === 'export') {
          return (
            <el-dropdown on-command={this.handleCommand}>
              <el-button size='mini' disabled={this.handleOpGroupDisabled(btn.children)}>
                导出<i class='el-icon-arrow-up el-icon--right'></i>
              </el-button>
              <el-dropdown-menu slot='dropdown'>
                {
                  this.renderMoreBtn(btn.children)
                }
              </el-dropdown-menu>
            </el-dropdown>
          );
        } else if (btn.key === 'more') {
          return (
            <el-dropdown on-command={this.handleCommand}>
              <el-button size='mini' disabled={this.handleOpGroupDisabled(btn.children)}>
                更多<i class='el-icon-arrow-up el-icon--right'></i>
              </el-button>
              <el-dropdown-menu slot='dropdown'>
                {
                  this.renderMoreBtn(btn.children)
                }
              </el-dropdown-menu>
            </el-dropdown>
          );
        } else {
          return (
            <el-button v-loading={ btn.loading } on-click={() => { this.handleTableOp(btn); }} disabled={this.handleOpDisabled(btn)} size='mini'>{btn.label}</el-button>
          );
        }
      });
    },
    getData() {
      return this.data;
    },
    getTotal() {
      return this.total;
    },
    async getDataFromServer() {
      // console.error(this.queryForm);
      this.data = [];
      this.loading = true;
      try {
        if (this.sortOrder) {
          this.sortOrder = this.sortOrder === 'ascending' ? 'asc' : 'desc';
        }
        if (!this.queryForm.sortName) {
          this.queryForm['sortName'] = this.sortName;
        }
        if (!this.queryForm.sortOrder) {
          this.queryForm['sortOrder'] = this.sortOrder;
        }
        if (this.queryForm.sortOrder) {
          const array = ['ascending', 'asc', 'ASC', 'Asc', 'Ascending'];
          this.queryForm.sortOrder = (array.includes(this.queryForm.sortOrder)) ? 'asc' : 'desc';
        }
        if (this.pagination) {
          this.queryForm['page'] = this.currentPage;
          this.queryForm['pageSize'] = this._pageSize || this.pageSize;
          const data = await this.loadData(this.queryForm);
          if (data) {
            this.data = this.setVirtualValue(data.data.result);
            this.total = data.data.total * 1;
          }
        } else {
          const data = await this.loadData(this.queryForm);
          this.data = this.setVirtualValue(data);
          this.total = this.data.length;
        }
        this.$emit('data-load-success', this.data);
      } catch (err) {
        console.error(err) // eslint-disable-line
        this.loading = false;
      }
      this.$nextTick(() => {
        this.loading = false;
      });
    },
    setVirtualValue(data) {
      // 添加一个临时变量，用于控制一些进度
      data && data.length > 0 && data.forEach(d => {
        d['_loading'] = false;
      });
      return data;
    },
    renderPagination() {
      if (this.pagination && this.hasPagination) {
        return (
          <el-pagination
            current-page={this.currentPage}
            background
            size='medium'
            page-size={this._pageSize || this.pageSize}
            page-sizes={this.pageSizes}
            total={this.total}
            on-current-change={this.handleCurrentChange}
            on-size-change={this.handleSizeChange}
            // small={this.pageSmall}
            pager-count={this.pagerCount * 1}
            layout={this.pageLayout}>
          </el-pagination>
        );
      }
    },
    renderColumn() {
      if (!this.columns || this.columns.length === 0) {
        return (
          <template></template>
        );
      } else {
        return this.columns.map(column => {
          const { formatter, renderBody } = column;
          const data = {
            props: {
              ...column,
              formatter: formatter && (row => formatter(row[column.prop])),
            },
          };

          if (renderBody) {
            data.scopedSlots = {
              default({ row }) {
                return renderBody('', row);
              },
            };
          }
          return (
            <el-table-column {...data}></el-table-column>
          );
        });
      }
    },
  },
  render(h) {
    const namespace = 'el-table-plus';
    const { caption, actionBar, ...otherSlots } = this.$slots;
    return (
      <div class={namespace}>
        {
          (caption || actionBar) &&
          <div class={`${namespace}__header`}>
            <h1 class={`${namespace}__header__caption`}>{caption}</h1>
            <div class={`${namespace}__header__action-bar`}>{actionBar}</div>
          </div>
        }
        <el-table ref='table' data={this.data} v-loading={this.loading}
          tooltip-effect={this.tooltipEffect}
          {...{
            props: this.$attrs, on: {
              ... this.$listeners,
              'sort-change': (c) => {
                this.sortName = c.prop ? c.prop : (c.column ? c.column.property : '');
                this.sortOrder = c.order;
                if (c.column.sortable === 'custom') {
                  this.queryForm['sortName'] = this.sortName;
                  this.queryForm['sortOrder'] = this.sortOrder;
                  this.handleCurrentChange(1);
                }
                this.$emit('sort-change', c);
              },
              'select-all': (s) => {
                this.checkAll = true;
                this.$emit('select-all', s);
              },
              'selection-change': (s) => {
                this.selection = s;
                this.checkAll = this.selection.length === this.data.length;
                this.$emit('selection-change', s);
              },
            },
          }}>
          {
            Object.entries(otherSlots).map(([key, val]) =>
              <template slot={key}>{val}</template>
            )
          }
          {
            this.renderColumn()
          }
        </el-table>
        <div class='table-pagination-box' v-show={this.data && this.data.length > 0 && (this.pagination || this.btnOpArray.length > 0)} >
          <div class='table-op-box pull-left'>
            <label v-show={this.btnOpArray.length > 0} role='checkbox' class={this.data.length === this.selection.length ? 'el-checkbox is-checked' : 'el-checkbox'}
              aria-checked={this.data.length === this.selection.length}
            >
              <span aria-checked='mixed' class={this.data.length === this.selection.length ? 'el-checkbox__input is-checked' : 'el-checkbox__input'}>
                <span class='el-checkbox__inner'></span>
                <input on-change={this.selectAll} checked={this.data.length === this.selection.length} type='checkbox' class='el-checkbox__original' value='' />
              </span>
            </label>
            {
              this.renderOpBtn()
            }
          </div>
          <div class='pull-right'>{this.renderPagination()}</div>
        </div>
      </div>
    );
  },
  watch: {
    opBtns() {
      this.calcBtn();
    },
  },
  mounted() {
    this.calcBtn();
  },
  created() {
    this.permissions = this.$store.state.user.permissions || [];
  },
};

